Bounded Contexts y Módulos
En un sistema suficientemente grande, el mismo concepto de negocio puede significar cosas distintas para distintas partes del sistema. Un Usuario para el módulo de autenticación tiene email, contraseña, descripción, rol...
Forzar un único modelo Usuario que sirva a todos estos contextos lleva inevitablemente a un objeto con docenas de campos, la mayoría nulos dependiendo de quién lo consulte. El modelo se vuelve inmanejable y frágil: cualquier cambio en un contexto puede romper los otros.
Qué es un Bounded Context
Un Bounded Context (BC) es el contexto desde el cual se mira un concepto de dominio. Define qué datos y comportamientos son relevantes para ese concepto en ese contexto concreto. Es la pieza que hace viable tener modelos pequeños y cohesionados.
Cada BC tiene su propio User con solo lo que necesita. No hay un User global.
Un Bounded Context es una unidad conceptual, no de despliegue. DWall tiene múltiples BCs en el mismo proceso JVM, en la misma base de datos (con prefijos de tabla por módulo). No hacen falta microservicios para aplicar BCs — es un patrón de organización del código.
BCs y la regla de no-cruce
La regla fundamental entre BCs es: un bounded context no accede directamente a los datos de otro. No hay JOINs cruzados entre módulos. No hay imports de clases de dominio de otro contexto.
Si el módulo de descripciones necesita el nombre de una variable, no hace SELECT name FROM variable WHERE id = ?. En su lugar, mantiene su propia copia del nombre en module_description_variable.name, que se actualiza cuando el módulo de variables publica un evento de cambio.
Esta restricción es deliberada. Garantiza que cada módulo puede evolucionar de forma independiente: si el módulo de variables cambia su esquema de base de datos, el módulo de descripciones no se entera — solo recibe eventos con los datos que le importan.
Módulos en xabet-digitalwall
En la práctica de DWall, un módulo Maven (dwall-module-*) es la unidad de bounded context:
dwall-core/
├── dwall-module-description/ ← BC: Descripciones textuales
├── dwall-module-files/ ← BC: Gestión de ficheros
├── dwall-module-embeddings/ ← BC: Embeddings vectoriales (TFG)
├── dwall-module-variables/ ← BC: Variables de planta
├── dwall-module-rules/ ← BC: Reglas de negocio
└── ...
Cada módulo tiene su propio esquema de base de datos (prefijo de tabla), sus propias entidades de dominio y sus propias migraciones Flyway. La comunicación entre módulos es exclusivamente mediante eventos de dominio — nunca mediante llamadas directas a repositorios de otro módulo.
El módulo de descripciones como BC
El módulo de descripciones es un bounded context con una identidad clara: gestionar el texto descriptivo asociado a recursos de DWall. Su dominio se limita a ese propósito.
Dentro del módulo, los recursos de otros BCs (variables, reglas, usuarios…) se representan de forma minimalista:
// DescriptionEntity.java — dentro de description-domain
@RequiredArgsConstructor
@Getter
public class DescriptionEntity {
private final Long id;
private final String entity; // "VARIABLE", "TAG", "USER", etc.
}El módulo no sabe qué es una Variable en el sentido del módulo de variables. Solo sabe que existe un tipo de entidad llamado "VARIABLE" con un id numérico. El resto — nombre, unidades, valor — pertenece a otro BC y no tiene cabida aquí.
BCs y el tamaño de los agregados
Una consecuencia directa de los BCs es que hacen viables los agregados pequeños. Sin BC, el modelo Description tendría que incluir el nombre de la variable, su unidad, su rango de valores… — todo lo que cualquier consumidor pudiera necesitar. Con BC, Description solo tiene {id, typeId, entityId, text, userId, timestamp}. Es pequeño, cohesionado y sin datos nulos.
Los agregados pequeños son posibles porque el BC define el límite de lo que es relevante. El capítulo siguiente analiza los bloques de construcción internos del dominio: cómo se modela ese agregado, qué son los Value Objects, y qué responsabilidades tiene el Aggregate Root.